<?php
declare(strict_types=1);

namespace app\service;

use think\facade\{Cache, Log, Http, Config};

class IpLocationService 
{
    // IP-API限制: 45次/分钟
    const IP_API_LIMIT = 45;
    // 百度限制: 6000次/天
    const BAIDU_LIMIT = 6000;
    
    /**
     * 获取IP地理位置信息
     */
    public function getLocation($ip)
    {
        try {
            // 先查询缓存
            $cacheKey = 'ip_location:' . $ip;
            if ($location = Cache::get($cacheKey)) {
                return $location;
            }
            
            // 检查限流
            if (!$this->checkRateLimit()) {
                throw new \Exception('IP查询频率超限');
            }
            
            // 根据配置选择服务商
            $provider = Config::get('ip.provider', 'ip-api');
            $location = match($provider) {
                'baidu' => $this->getBaiduLocation($ip),
                'ip-api' => $this->getIpApiLocation($ip),
                default => throw new \Exception('未知的IP定位服务商')
            };
            
            if ($location) {
                // 缓存结果,有效期7天
                Cache::set($cacheKey, $location, 7 * 86400);
            }
            
            return $location;
        } catch (\Exception $e) {
            Log::error('IP地理位置查询失败: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 检查限流
     */
    protected function checkRateLimit()
    {
        $provider = Config::get('ip.provider', 'ip-api');
        $key = "ip_query_count:{$provider}:" . date('YmdH');
        $count = Cache::get($key, 0);
        
        $limit = match($provider) {
            'baidu' => self::BAIDU_LIMIT,
            'ip-api' => self::IP_API_LIMIT,
            default => 0
        };
        
        if ($count >= $limit) {
            return false;
        }
        
        // 计数+1,有效期1小时
        Cache::set($key, $count + 1, 3600);
        return true;
    }

    /**
     * 调用百度IP定位服务
     */
    protected function getBaiduLocation($ip)
    {
        $ak = Config::get('ip.baidu_ak');
        if (!$ak) {
            throw new \Exception('未配置百度IP定位服务密钥');
        }

        $response = Http::get("https://api.map.baidu.com/location/ip", [
            'ak' => $ak,
            'ip' => $ip,
            'coor' => 'bd09ll'
        ]);
        
        $result = json_decode($response, true);
        if (!$result || $result['status'] !== 0) {
            throw new \Exception('百度IP地址查询失败');
        }

        return [
            'country' => '中国',
            'province' => $result['content']['address_detail']['province'] ?? '',
            'city' => $result['content']['address_detail']['city'] ?? '',
            'district' => $result['content']['address_detail']['district'] ?? '',
            'isp' => $result['content']['address_detail']['isp'] ?? ''
        ];
    }

    /**
     * 调用ip-api定位服务
     */
    protected function getIpApiLocation($ip)
    {
        $response = Http::get("http://ip-api.com/json/{$ip}?lang=zh-CN");
        $result = json_decode($response, true);
        
        if (!$result || $result['status'] !== 'success') {
            throw new \Exception('IP-API地址查询失败');
        }

        return [
            'country' => $result['country'] ?? '',
            'province' => $result['regionName'] ?? '',
            'city' => $result['city'] ?? '',
            'district' => '',
            'isp' => $result['isp'] ?? ''
        ];
    }
} 